[id].tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import { useFormState } from "react-use-form-state";
  2. import { Flex } from "reflexbox/styled-components";
  3. import React, { useState } from "react";
  4. import { NextPage } from "next";
  5. import { useRouter } from "next/router";
  6. import axios from "axios";
  7. import AppWrapper from "../../components/AppWrapper";
  8. import { TextInput } from "../../components/Input";
  9. import { Button } from "../../components/Button";
  10. import Text, { H2 } from "../../components/Text";
  11. import { Col } from "../../components/Layout";
  12. import Icon from "../../components/Icon";
  13. import { APIv2 } from "../../consts";
  14. interface Props {
  15. protectedLink?: string;
  16. }
  17. const ProtectedPage: NextPage<Props> = () => {
  18. const router = useRouter();
  19. const [loading, setLoading] = useState(false);
  20. const [formState, { password }] = useFormState<{ password: string }>();
  21. const [error, setError] = useState<string>();
  22. const onSubmit = async e => {
  23. e.preventDefault();
  24. const { password } = formState.values;
  25. if (!password) {
  26. return setError("Password must not be empty.");
  27. }
  28. setError("");
  29. setLoading(true);
  30. try {
  31. const { data } = await axios.post(
  32. `${APIv2.Links}/${router.query.id}/protected`,
  33. {
  34. password
  35. }
  36. );
  37. window.location.replace(data.target);
  38. } catch ({ response }) {
  39. setError(response.data.error);
  40. }
  41. setLoading(false);
  42. };
  43. return (
  44. <AppWrapper>
  45. {!router.query.id ? (
  46. <H2 my={4} light>
  47. 404 | Link could not be found.
  48. </H2>
  49. ) : (
  50. <Col width={500} maxWidth="97%">
  51. <H2 my={3} bold>
  52. Protected link
  53. </H2>
  54. <Text mb={4}>Enter the password to be redirected to the link.</Text>
  55. <Flex
  56. as="form"
  57. alignItems="center"
  58. onSubmit={onSubmit}
  59. style={{ position: "relative" }}
  60. >
  61. <TextInput
  62. {...password("password")}
  63. placeholder="Password"
  64. height={[44, 54]}
  65. width={[1, 1 / 2]}
  66. mr={3}
  67. autoFocus
  68. required
  69. />
  70. <Button type="submit" height={[40, 44]}>
  71. {loading && <Icon name={"spinner"} stroke="white" mr={2} />}
  72. Go
  73. </Button>
  74. </Flex>
  75. <Text fontSize={14} color="red" mt={3} normal>
  76. {error}
  77. </Text>
  78. </Col>
  79. )}
  80. </AppWrapper>
  81. );
  82. };
  83. ProtectedPage.getInitialProps = async ({ req }) => {
  84. return {
  85. protectedLink: req && (req as any).protectedLink
  86. };
  87. };
  88. export default ProtectedPage;